{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "659d0daf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import plotly.express as px\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "from sklearn import metrics\n",
    "import sklearn.metrics as mt\n",
    "from collections import Counter\n",
    "\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.svm import SVC, LinearSVC\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from xgboost import XGBClassifier\n",
    "import lightgbm as lgb\n",
    "from sklearn.ensemble import GradientBoostingClassifier\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.metrics import roc_auc_score\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "\n",
    "import os\n",
    "parent_dir = os.path.abspath(os.path.join(os.getcwd(), '..'))\n",
    "\n",
    "import sys\n",
    "sys.path.append(parent_dir)\n",
    "\n",
    "import balanceDataset as balance\n",
    "import modelTrainingAndPerformance as mtap\n",
    "\n",
    "import shap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0502229",
   "metadata": {},
   "source": [
    "## Dataset Description"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0b88b8d",
   "metadata": {},
   "source": [
    "- step - maps a unit of time in the real world. In this case 1 step is 1 hour of time. Total steps 744 (30 days simulation).\n",
    "- type - CASH-IN, CASH-OUT, DEBIT, PAYMENT and TRANSFER.\n",
    "- amount - amount of the transaction in local currency.\n",
    "- nameOrig - customer who started the transaction\n",
    "- oldbalanceOrg - initial balance before the transaction\n",
    "- newbalanceOrig - new balance after the transaction\n",
    "- nameDest - customer who is the recipient of the transaction\n",
    "- oldbalanceDest - initial balance recipient before the transaction. Note that there is not information for customers that start with M (Merchants).\n",
    "- newbalanceDest - new balance recipient after the transaction. Note that there is not information for customers that start with M (Merchants).\n",
    "- isFraud - This is the transactions made by the fraudulent agents inside the simulation. In this specific dataset the fraudulent behavior of the agents aims to profit by taking control or customers accounts and try to empty the funds by transferring to another account and then cashing out of the system.\n",
    "- isFlaggedFraud - The business model aims to control massive transfers from one account to another and flags illegal attempts. An illegal attempt in this dataset is an attempt to transfer more than 200.000 in a single transaction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6e3958c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.read_csv('paysim.csv')\n",
    "df = data.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "10fe839f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>step</th>\n",
       "      <th>type</th>\n",
       "      <th>amount</th>\n",
       "      <th>nameOrig</th>\n",
       "      <th>oldbalanceOrg</th>\n",
       "      <th>newbalanceOrig</th>\n",
       "      <th>nameDest</th>\n",
       "      <th>oldbalanceDest</th>\n",
       "      <th>newbalanceDest</th>\n",
       "      <th>isFraud</th>\n",
       "      <th>isFlaggedFraud</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>PAYMENT</td>\n",
       "      <td>9839.64</td>\n",
       "      <td>C1231006815</td>\n",
       "      <td>170136.0</td>\n",
       "      <td>160296.36</td>\n",
       "      <td>M1979787155</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>PAYMENT</td>\n",
       "      <td>1864.28</td>\n",
       "      <td>C1666544295</td>\n",
       "      <td>21249.0</td>\n",
       "      <td>19384.72</td>\n",
       "      <td>M2044282225</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>TRANSFER</td>\n",
       "      <td>181.00</td>\n",
       "      <td>C1305486145</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>C553264065</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>CASH_OUT</td>\n",
       "      <td>181.00</td>\n",
       "      <td>C840083671</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>C38997010</td>\n",
       "      <td>21182.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>PAYMENT</td>\n",
       "      <td>11668.14</td>\n",
       "      <td>C2048537720</td>\n",
       "      <td>41554.0</td>\n",
       "      <td>29885.86</td>\n",
       "      <td>M1230701703</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   step      type    amount     nameOrig  oldbalanceOrg  newbalanceOrig  \\\n",
       "0     1   PAYMENT   9839.64  C1231006815       170136.0       160296.36   \n",
       "1     1   PAYMENT   1864.28  C1666544295        21249.0        19384.72   \n",
       "2     1  TRANSFER    181.00  C1305486145          181.0            0.00   \n",
       "3     1  CASH_OUT    181.00   C840083671          181.0            0.00   \n",
       "4     1   PAYMENT  11668.14  C2048537720        41554.0        29885.86   \n",
       "\n",
       "      nameDest  oldbalanceDest  newbalanceDest  isFraud  isFlaggedFraud  \n",
       "0  M1979787155             0.0             0.0        0               0  \n",
       "1  M2044282225             0.0             0.0        0               0  \n",
       "2   C553264065             0.0             0.0        1               0  \n",
       "3    C38997010         21182.0             0.0        1               0  \n",
       "4  M1230701703             0.0             0.0        0               0  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2ab5b2ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6362620, 11)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "af8c5cac",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 6362620 entries, 0 to 6362619\n",
      "Data columns (total 11 columns):\n",
      " #   Column          Dtype  \n",
      "---  ------          -----  \n",
      " 0   step            int64  \n",
      " 1   type            object \n",
      " 2   amount          float64\n",
      " 3   nameOrig        object \n",
      " 4   oldbalanceOrg   float64\n",
      " 5   newbalanceOrig  float64\n",
      " 6   nameDest        object \n",
      " 7   oldbalanceDest  float64\n",
      " 8   newbalanceDest  float64\n",
      " 9   isFraud         int64  \n",
      " 10  isFlaggedFraud  int64  \n",
      "dtypes: float64(5), int64(3), object(3)\n",
      "memory usage: 534.0+ MB\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d95722a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "step              0\n",
       "type              0\n",
       "amount            0\n",
       "nameOrig          0\n",
       "oldbalanceOrg     0\n",
       "newbalanceOrig    0\n",
       "nameDest          0\n",
       "oldbalanceDest    0\n",
       "newbalanceDest    0\n",
       "isFraud           0\n",
       "isFlaggedFraud    0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c307590e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    " df.duplicated().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ad475b27",
   "metadata": {},
   "outputs": [],
   "source": [
    "#df = df.drop(columns = ['step', 'isFlaggedFraud'], axis = 'columns') #gereksiz sütunları çıkardık"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7ffefebc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['PAYMENT', 'TRANSFER', 'CASH_OUT', 'DEBIT', 'CASH_IN'],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.type.unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0899fb3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "#fig = px.box(df, y=\"amount\")\n",
    "#fig.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3393e60d",
   "metadata": {},
   "source": [
    "## EDA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "870975fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    6354407\n",
       "1       8213\n",
       "Name: isFraud, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['isFraud'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c2e248dd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "C1305486145    1\n",
       "C202278158     1\n",
       "C12585107      1\n",
       "C946427395     1\n",
       "C1069177491    1\n",
       "              ..\n",
       "C2090764492    1\n",
       "C1794935564    1\n",
       "C318078280     1\n",
       "C939293281     1\n",
       "C1685995037    1\n",
       "Name: nameOrig, Length: 4097, dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# İşlemlerin yapıldığı kaynağın kontrol edilmesi.\n",
    "transfer_df = df[((df['type']=='TRANSFER') & df['isFraud']==1)] \n",
    "transfer_df['nameOrig'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5ba455e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "C200064275     2\n",
       "C1399829166    2\n",
       "C1650668671    2\n",
       "C2129197098    2\n",
       "C1013511446    2\n",
       "              ..\n",
       "C1566713324    1\n",
       "C1955464150    1\n",
       "C1104137869    1\n",
       "C377165949     1\n",
       "C873221189     1\n",
       "Name: nameDest, Length: 4091, dtype: int64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# İşlemlerin nakde çevrildiği varış noktasının kontrol edilmesi.\n",
    "cash_out_fraud = df[(df['type'] == 'CASH_OUT') & (df['isFraud'] == 1)]\n",
    "cash_out_fraud['nameDest'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fff73f02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nakit çekmek için kullanılan alıcı hesabı var mı?\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fraud_trans = df[df['isFraud'] == 1]\n",
    "valid_trans = df[df['isFraud'] == 0]\n",
    "\n",
    "trans_transfer = df[df['type'] == 'TRANSER']\n",
    "trans_cashout = df[df['type'] == 'CASH_OUT']\n",
    "\n",
    "print('Nakit çekmek için kullanılan alıcı hesabı var mı?')\n",
    "trans_transfer.nameDest.isin(trans_cashout.nameOrig).any()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b42bc862",
   "metadata": {},
   "source": [
    "plt.figure(figsize=(10,5))\n",
    "sns.heatmap(df.corr(),annot=True);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fd91e26",
   "metadata": {},
   "source": [
    "sns.violinplot(x = df['isFraud'],y = df['amount']);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "575c97c8",
   "metadata": {},
   "source": [
    "sns.violinplot(x = df['isFraud'],y = df[df['oldbalanceOrg']<100000].oldbalanceOrg);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1ed9c5a",
   "metadata": {},
   "source": [
    "sns.boxplot(x=df.isFraud,y=df.step);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5706a2c",
   "metadata": {},
   "source": [
    "plt.figure(figsize=(10,8))\n",
    "plt.pie(df.type.value_counts().values,labels=df.type.value_counts().index,  autopct='%.0f%%')\n",
    "plt.title(\"Transaction Type\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69bff6a8",
   "metadata": {},
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "encoder = {}\n",
    "for i in df.select_dtypes('object').columns:\n",
    "    encoder[i] = LabelEncoder()\n",
    "    df[i] = encoder[i].fit_transform(df[i])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "576eda4b",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>step</th>\n",
       "      <th>amount</th>\n",
       "      <th>nameOrig</th>\n",
       "      <th>oldbalanceOrg</th>\n",
       "      <th>newbalanceOrig</th>\n",
       "      <th>nameDest</th>\n",
       "      <th>oldbalanceDest</th>\n",
       "      <th>newbalanceDest</th>\n",
       "      <th>isFraud</th>\n",
       "      <th>isFlaggedFraud</th>\n",
       "      <th>type__CASH_IN</th>\n",
       "      <th>type__CASH_OUT</th>\n",
       "      <th>type__DEBIT</th>\n",
       "      <th>type__PAYMENT</th>\n",
       "      <th>type__TRANSFER</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>9839.64</td>\n",
       "      <td>C1231006815</td>\n",
       "      <td>170136.0</td>\n",
       "      <td>160296.36</td>\n",
       "      <td>M1979787155</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1864.28</td>\n",
       "      <td>C1666544295</td>\n",
       "      <td>21249.0</td>\n",
       "      <td>19384.72</td>\n",
       "      <td>M2044282225</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>181.00</td>\n",
       "      <td>C1305486145</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>C553264065</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>181.00</td>\n",
       "      <td>C840083671</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>C38997010</td>\n",
       "      <td>21182.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>11668.14</td>\n",
       "      <td>C2048537720</td>\n",
       "      <td>41554.0</td>\n",
       "      <td>29885.86</td>\n",
       "      <td>M1230701703</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   step    amount     nameOrig  oldbalanceOrg  newbalanceOrig     nameDest  \\\n",
       "0     1   9839.64  C1231006815       170136.0       160296.36  M1979787155   \n",
       "1     1   1864.28  C1666544295        21249.0        19384.72  M2044282225   \n",
       "2     1    181.00  C1305486145          181.0            0.00   C553264065   \n",
       "3     1    181.00   C840083671          181.0            0.00    C38997010   \n",
       "4     1  11668.14  C2048537720        41554.0        29885.86  M1230701703   \n",
       "\n",
       "   oldbalanceDest  newbalanceDest  isFraud  isFlaggedFraud  type__CASH_IN  \\\n",
       "0             0.0             0.0        0               0              0   \n",
       "1             0.0             0.0        0               0              0   \n",
       "2             0.0             0.0        1               0              0   \n",
       "3         21182.0             0.0        1               0              0   \n",
       "4             0.0             0.0        0               0              0   \n",
       "\n",
       "   type__CASH_OUT  type__DEBIT  type__PAYMENT  type__TRANSFER  \n",
       "0               0            0              1               0  \n",
       "1               0            0              1               0  \n",
       "2               0            0              0               1  \n",
       "3               1            0              0               0  \n",
       "4               0            0              1               0  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df=pd.concat([df,pd.get_dummies(df['type'], prefix='type_')],axis=1)\n",
    "df.drop(['type'],axis=1,inplace = True)\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1e8143b",
   "metadata": {},
   "source": [
    "## Sonuçlar\n",
    "\n",
    "* Dolandırıcılık işlemlerimiz TRANSFER ve CASH_OUT işlem tipinde yapılmaktadır.\n",
    "\n",
    "* TRANSFER'deki dolandırıcılık işlemleri 4097 ve CASH_OUT 4116 adet.\n",
    "\n",
    "* Dolandırıcılık işlemleri genellikle Müşteriden Müşteriye yapılmakta.\n",
    "\n",
    "* Alım ve Gönderim için kullanılan işlem hesabı, Dolandırıcılık işlemlerinde Aynı değil."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab5bb4e1",
   "metadata": {},
   "source": [
    "## Preprocessing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "c2fcb6de",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns\n",
    "numeric_columns.size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "5311ce5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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AAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjssNKVwAAxuKss87KgQceuNLVYPCkJz0pz33uc1e6GlulK664IqeffrrvKyzBoYcemne9611prc1cv8cee+SSSy7JT37yk9zmNrfJ+eefn6pKay1PfOIT85GPfCRJsssuu+Siiy7KIYcckhNPPDE77LBD1q1bt77cl7/85XnoQx+aCy64IC94wQty5plnZs2aNdlnn32y00475QUveEGOPvrovPzlL0+SvOIVr8jznve8vPa1r81ZZ52VvfbaKzvttFOOOuqoJMlLX/rSXHPNNUmSqsr222+fZz7zmXnpS1+afffdN3/4h3+4vrzTTz89r3zlK7NmzZpst9122XPPPXPeeeetP79zzjknL3vZy3LcccflyiuvzHnnnZd99tknz372s9cfZ926dXnBC16Qk08+Oc973vNy9NFH57DDDsvLXvayvPGNb0ySHH744WmtZY899sgFF1yQF77whXn961+fN77xjTnggANmtu/HP/7xvPKVr8yOO+6Y/fbbL695zWvWn/90W8x9vfvuu+eCCy5Y305veMMbbtAes9p07r6LlXv00Uev/z1Zn+R6+89attRzWKq5x5t1/MX2W+zYSy1zKfVj6+MzWtzpp5+eJOInYFXacccd8+pXvzpve9vbUlV5/vOfvz4+WrNmTf70T/80F110UY444oi84hWvyLHHHjszxkmStWvX5vDDD8/tbne7bL/99lmzZk2e+cxn5mUve1le8YpX5G1ve1vWrVu3fvtJ+cnsWGOha9DGXJ/Wrl2bI444Yt7YcmPio5e+9KVpreWoo46ad9vlqvdy7Lcp5W2L1/4t2b5bi5rvD9nrbVR1UJI3Jtk+yd+31l6z0Pb3ute92mmnnbY8NZzHEUcckSTr/5hk63bEEUfki985L1f9zCErXZXNbpdvnpAk28S5LmaXb56Qe95xT/9O2SYcccQR628KsPU49dRTN2v5VfXF1tq9lqOsLRE/PexhD8t11123WY8BbJoddtghp5xySt7whjfkQx/60A3W77///jnzzDPz+Mc/Pq21fPjDH85+++2XM84443rbPeEJT0hrbWYZu+66ay6//PIblHf88cdf7ybNfPWbu810eUlPrCXJfvvtlzPPPDM3velNc/nll2f//fdPkhvUdVLm/vvvn3e84x0zj/uIRzziesednN+HP/zh67XF3Ne///u/nze84Q3zttPcNphv38XKPfPMM9f/nqxPcr39Zy1b6jks1dzjzTr+YvstduyllrmU+rH12ZKf0XLFT1sidkp6/JREDAWsenNjwen46AlPeEJOP/30nHHGGdl1111zxRVXzIxxkuQZz3jGDWKrSdlz48Pp8ueLNRa6Bm3M9WlSr/liy42Jjyax9BOe8IR5t12uei/HfptS3rYYn23J9l1umxo/LToFaFVtn+RNSQ5OcpckT62qu2x8FQFgvM4666yVrgIzvOlNb1rpKgAsybp16/LhD384xx9//Mz1Z5xxRlprOfHEE3PiiSemtTYzqXXCCSfkxBNPnFnG9M2YSXkf+chHFk3+Teq3UHlJ0lpbX6/W2vr1Z5xxxsy6Tso844wzsnbt2hus//jHP36D4x5//PE56aST1rfFrNcnnXRS1q5du/79rGNPt8F0m87dd7Fyp3+fdNJJueCCC3LBBRdcb5+5y+bWe3LsufW44IILFv1cktzgeNN1XKic+eo0a59Z57RUN2Zftgyf0eIk/4AxmBsLTjv++OPXL7v88stnxjhJH2U3K7aalD0r+Zf0GHXWtWaha9DGXJ+m6zUrtlxqWZPtJk488cSZ2y5XvTeljku1Oeq4mm3J9t2aLGUK0HsnWdta+06SVNX7kjwhydc3Z8UWc8455+Sqq65aPxKQrdvatWuz3U8WH23KuGz340uzdu1l/p2yTbjwwgtXugrMcNxxx5kGFFg13vCGN8w71ejEZBrLTV0/17XXXrtR228uRx111A16ar/61a++wXbr1q1bP9Jw+lynX1977bU56qijlnzDfqF9N6bca6+9Nscee2xaa+u3mbVsvnrPPdaxxx67pJ7E73znO693vOk6LlTO9H6LHXvuMZZatxu7L1uGz2hhkn/AtmChDmHT14bJdPMb65prrlkfw02Xt9A1aGOuT3PrNTe2XGpZ73znO28Qn83adrnqvdQyN8XmqONqtiXbd2uy6AjAJHsnmR7WcPaw7Hqq6v9W1WlVddoPf/jD5aofAMBoiZ+AaUt5PMNklN3YLDRCcK7J+U+3xfTrdevW5YwzzljSyMbF9t2YctetW5eTTz45p5xyyvptZi2br95zj3XyyScvqf5zjzddx4XKma9Os/aZdU5LdWP2ZctYTZ+R2Algy5u+Nsw3s8JSzIo1FroGbcz1aW695r5falmnnHLK9WLt1trMbZer3ptSx6XaHHVczbZk+25NljICsGYsu8FfnK21tyZ5a9LnYb+R9VrU3nv3HKRni60Ok2cAsm25bueb5wDPAGQbceCBB650FViFtnT8BGzdqmrR5N6k5/TYkoCT5wROm/XcwWRDO023xfTrHXbYIfvss0/OPvvsJSUBF9p3Y8rdYYcd8shHPjKttZxwwglZt27dzGXz1XvusR75yEcuWvekPydx+njTdVyonOn9Fjv23GMstW43dl+2jNX0Ga1E7LTddtsZBQhs06avDXOfHbgxJjHcdHkLXYM25vo0t15zY8ullvWIRzwiH/7wh9fH2lU1c9vlqvem1HGpNkcdV7Mt2b5bk6WMADw7yb5T7/dJ8v3NUx0AWJ122223la4CMzzpSU9a6SoALNnzn//8bL/99gtus2bNmuyww/z9ONesWZM1a9Ys+ZiLHW9LeclLXnKDZS960YtusGyHHXZYf37T5zr9evvtt89LXvKSbLfdUv7cvX6bzt13Y8rdfvvtc+ihh+awww5bv82sZXPrPTn23HoceuihS6r/3ONN13Ghcuar06x9Zp3TUt2YfdkyfEYALBRfTl8bZsVsSzFfrLHQNWhjrk9z6zX3/VLLOuyww64XS69Zs2bmtstV702p41JtjjquZluyfbcmS/mL6AtJfqqq7lBVOyZ5SpIPbd5qAcDqsu+++y6+EVuc5/8Bq8UOO+yQxz3ucXnMYx4zc/3++++fqsrBBx+cgw8+OFU1c9TcIYcckoMPPnhmGbvuuusNynvsYx+74A2f6fotVF7Se0hP6lVV69fvv//+847wm6w/4IADbrD+YQ972A2O+5jHPCYHHXTQ+raY9fqggw7KAQccsP79rGNPt8F0m87dd7Fyp38fdNBB2X333bP77rtfb5+5y+bWe3LsufXYfffdF/1cktzgeNN1XKic+eo0a59Z57RUN2Zftgyf0eKW2qEAYGs2Nxac9pjHPGb9sl133XVmjJMkBxxwwMzYalL23Phw4pBDDpl5rVnoGrQx16fpes2KLZda1mS7iYMPPnjmtstV702p41JtjjquZluyfbcmi/6l11pbV1W/m+SjSbZP8vbW2tc2e80AYJXZbbfdcuGFF650NRgY/Qcsh0MPPTTvete75p1yc4899sgll1ySn/zkJ7nNbW6T888/f/30Rk984hPzkY98JEmyyy675KKLLsohhxySE088cf30lpNyX/ziFyfpPUm/8pWv5Mwzz8yaNWuyzz77ZKeddsoLXvCCHH300et7lp5xxhl53vOel9e+9rU566yzstdee2WnnXZav37t2rW55pprkvTE3Pbbb59nPvOZeelLX5p99903f/iHf7i+vLvf/e555StfmTVr1mS77bbLnnvumfPOO2/9+Z1zzjl58YtfnOOOOy5XXnllzjvvvOyzzz559rOfnZe+9KW55pprsm7dujz/+c/PySefnOc973k5+uijc9hhh+VlL3vZ+h7Yhx9+eFpr2WOPPXLBBRfkhS98YV7/+tcv2JP8RS96UV75yldmxx13zH777Xe981/s9WGHHba+nd7whjfcoD1mtencfRcr9+ijj17/e26v6ul9FitzvtdLNbfsWcdfyn4L7bPUMpd7X7YMnxHAuO2444458sgj87a3vS1Vlec///nr46PJKLeLLrooRxxxRI488sgce+yxM2OcpI+uO/zww3O7290u22+/fdasWZNnPvOZednLXrb+GNPTpU+Popt1rVnoGrQx16eXvOQlOeKII+aNLTcmPlq7dm1aawtuu1z1Xo79tmQdV7Mt2b5bi9ocz464173u1U477bRlL3faEUcckcQzAFeLyTMAr/qZQ1a6KpvdLt88IUm2iXNdzC7fPCH39AxAthGuS9umqvpia+1ey1HWloifHvawh+W6667LTW960xxwwAG+rwDAFrdc8dOWiJ2SHj8lyd3udrck4n0AYMvb1PjJHAYAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIjusdAU21QEHHLDSVQCA9VyXWA222267XHfdddlll118ZwEAlmC77XrfebETALDarNoE4OGHH77SVQCA9VyXWA122mmnrFu3LnvvvbfvLADAEuy0005JxPsAwOpjClAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABiRHVa6Amw7tr/ywuzyzRNWuhqb3fZXXpAk28S5Lmb7Ky9MsudKVwMAAAAAALYpEoBsEQcccMBKV2GLOeecdUmSvfeW+Er23KY+e4Ct3e1ud7tcfPHF/m8GAFiigw46aKWrAACwSSQA2SIOP/zwla4CAGzz/v7v/36lqwAAsKq4nwEArFaeAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACNSrbXlL7Tqh0nOXPaCr+/WSX60mY+xGmmX2bTL/LTNbNplNu0ym3aZbVtol/1aa3ssR0FbKH5Kto3PZcx8fqufz3D18xmubj6/lbcs8dMWjJ0S35vNSdtuPtp289K+m4+23by07+azOdt2k+KnzZIA3BKq6rTW2r1Wuh5bG+0ym3aZn7aZTbvMpl1m0y6zaZetk89ldfP5rX4+w9XPZ7i6+fzYFL43m4+23Xy07ealfTcfbbt5ad/NZ2tsW1OAAgAAAAAAwIhIAAIAAAAAAMCIrOYE4FtXugJbKe0ym3aZn7aZTbvMpl1m0y6zaZetk89ldfP5rX4+w9XPZ7i6+fzYFL43m4+23Xy07ealfTcfbbt5ad/NZ6tr21X7DEAAAAAAAADghlbzCEAAAAAAAABgjlWXAKyqg6rqW1W1tqr+eKXrs6VV1dur6vyq+urUst2q6uSq+vbw+1ZT6/5kaKtvVdWjV6bWm19V7VtV/6+qvlFVX6uqI4bl23TbVNXOVfX5qjp9aJdXDMu36XaZqKrtq+q/quojw/ttvl2q6oyq+u+q+nJVnTYs0y5Vt6yqD1bVN4f/Z+6nXZKquvPwXZn8XFpVv6dttk7begy12s0X67C6zI09WF1mxQMrXSc2TlX9/vB/6Fer6r1VtfNK14mtm/hp85l1f4vlIW7cfOa7z8byEjNvHrPu+bF8tta/FVZVArCqtk/ypiQHJ7lLkqdW1V1WtlZb3DuSHDRn2R8n+ffW2k8l+ffhfYa2eUqSuw77/M3QhmO0LskLWms/m+S+SZ47nP+23jZXJ3lYa+3uSe6R5KCqum+0y8QRSb4x9V67dA9trd2jtXav4b12Sd6Y5KTW2s8kuXv692abb5fW2reG78o9ktwzyZVJ/iXaZqsjhhqF+WIdVpe5sQery6x4gFWiqvZO8rwk92qt/VyS7dPjEphJ/LTZvSM3vL/F8hA3bj7z3WdjeYmZN5+59/xYPlvl3wqrKgGY5N5J1rbWvtNa+0mS9yV5wgrXaYtqrX0yyYVzFj8hyTuH1+9M8stTy9/XWru6tfbdJGvT23B0Wmvntta+NLy+LP0f2N7ZxtumdZcPb9cMPy3beLskSVXtk+QxSf5+avE23y7z2KbbpapunuTBSd6WJK21n7TWLs423i4zPDzJ/7bWzoy22Rpt8zHUardArMMqMU/swSqxQDzA6rJDkl2qaockN0ny/RWuD1s38dNmNM/9LZaBuHHzWeA+G8tEzMxqtDX/rbDaEoB7Jzlr6v3ZcQFLkj1ba+cm/SKf5DbD8m2yvapq/yS/kORz0TaTYfNfTnJ+kpNba9ql+6skf5jkuqll2qUHrh+rqi9W1f8dlm3r7XLHJD9M8g/DFBR/X1U3jXaZ6ylJ3ju81jZbH20/InNiHVaPv8oNYw9Wj/niAVaJ1to5Sf4iyfeSnJvkktbax1a2VmzlxE+seuLG5TfPfTaWz19FzLy5zLrnx/LYav9WWG0JwJqxTC+L+W1z7VVVuyb5pyS/11q7dKFNZywbZdu01q4dpufbJ8m9q+rnFth8m2iXqnpskvNba19c6i4zlo2uXQYPaK39Yvo0N8+tqgcvsO220i47JPnFJH/bWvuFJFdkmNJyHttKu6xXVTsmeXyS4xbbdMayUbfNVkTbj8RGxDpsRTYh9mDrs7HxAFuZ4ZnET0hyhyR7JblpVT19ZWvFVk78xKombtw8NvI+GxtBzLzZbcw9PzbOVvu3wmpLAJ6dZN+p9/vElB1Jcl5V3S5Jht/nD8u3qfaqqjXpgc0/ttb+eVisbQbDsONT0+fY39bb5QFJHl9VZ6RP4/Kwqnp3tEtaa98ffp+f/iy3e0e7nJ3k7KlefR9Mv6hv6+0y7eAkX2qtnTe81zZbH20/AvPEOqwO88UerB7zxQOsHo9I8t3W2g9ba9ck+eck91/hOrF1Ez+xaokbN78599lYHmLmzWiee34sj632b4XVlgD8QpKfqqo7DKMNnpLkQytcp63Bh5IcNrw+LMm/TS1/SlXtVFV3SPJTST6/AvXb7Kqq0ufY/UZr7Q1Tq7bptqmqParqlsPrXdL/6P1mtvF2aa39SWttn9ba/un/j3y8tfb0bOPtUlU3raqbTV4neVSSr2Ybb5fW2g+SnFVVdx4WPTzJ17ONt8scT82G6T8TbbM1EkOtcgvEOqwCC8QerBILxAOsHt9Lct+qusnwf+rD05+LBfMRP7EqiRs3nwXus7EMxMybzwL3/FgGW/PfCjusdAU2RmttXVX9bpKPJtk+ydtba19b4WptUVX13iQHJrl1VZ2d5OVJXpPkA1X1zPQ/ap6UJK21r1XVB9K/bOuSPLe1du2KVHzze0CS30zy38M83Enyomib2yV5Z1Vtn57w/0Br7SNV9dls2+0yn239+7Jnkn/pfytkhyTvaa2dVFVfyLbdLklyeJJ/HP7w/06S38rwb2obb5dU1U2SPDLJs6cWb+v/lrY6YqhRmBnrtNZOWLkqwTZnVjzAKtFa+1xVfTDJl9LjkP9K8taVrRVbM/HT5jXr/lZr7W0rW6vREDduPjPvs61wnWApZt7zW9kqjc5W+bdCtWb6cgAAAAAAABiL1TYFKAAAAAAAALAACUAAAAAAAAAYEQlAAAAAAAAAGBEJQAAAAAAAABgRCUAAAAAAFlRVb6+q86vqq0vY9i+r6svDz/9U1cVboIoAAFuVlY6fqrV2Y8sAAAAAYMSq6sFJLk9ybGvt5zZiv8OT/EJr7f9stsoBAGyFVjp+MgIQAAAAgAW11j6Z5MLpZVV1p6o6qaq+WFWfqqqfmbHrU5O8d4tUEgBgK7LS8dMON7YAAAAAALZJb03ynNbat6vqPkn+JsnDJiurar8kd0jy8RWqHwDA1maLxU8SgAAAAABslKraNcn9kxxXVZPFO83Z7ClJPthau3ZL1g0AYGu0peMnCUAAAAAANtZ2SS5urd1jgW2ekuS5W6Y6AABbvS0aP3kGIAAAAAAbpbV2aZLvVtWTkqS6u0/WV9Wdk9wqyWdXqIoAAFuVLR0/SQACAAAAsKCqem/6zag7V9XZVfXMJE9L8syqOj3J15I8YWqXpyZ5X2utbfnaAgCsvJWOn0ocBgAAAAAAAONhBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCBsJaqqVdUBm7jvGVX1iOWu0+ZWVbevqsuravvNeIz9h7bdYXMdYyVV1Zur6qUrXQ8AWKqqekdVHbXA+vUx0WLbLnKcI6vq3Ztaz21FVT2jqj690vXYXKrqa1V14ErXAwBWwrZ4r2lLq6pTq+pZK12PzaGqHlRV31rpegCbTgIQWBZVdZeq+lBVXVJVl1XV/6uq+y+0T2vte621XVtr126peo5Na+05rbU/vbHlDIH9VUNC9vKq+tgC2z50+HwvqaozZqy/R1V9alh/dlW97MbWDwBWm6lOSJNr63lV9ZGqeuQylj3KDk7LqbV219baqTemjKrasao+OMRLbW5CsapuWVXvrKrzh58jFynvWVW1dvhenFRVe02t+4Oq+uoQT3+3qv7gxtQdAFaroTPXNcM18bKq+p+q+uuqut0yla2j2CJaa59qrd35xpazhPtI96+qzw+f81eq6oELlPV7VfWdqrq0qr5fVX85HRNvzP0t2BZIAAI3WlXdKclnkvx3kjsk2SvJvyT5WFXdb5593LDa+jxuSMju2lp71ALbXZHk7UnmuyH1niSfTLJbkock+f+q6vHLW1UAWDVu2VrbNcndk5yc5F+q6hkrWyU2waeTPD3JD2as+8skN0myf5J7J/nNqvqtWYVU1UOSvDrJE9Jjpe8mee/0JkkOTXKrJAcl+d2qesrynAIArDrvb63dLP2a+StJbpvki8uRBGSLmvc+UlXtluRDSf48yS2TvC7Jh6vqVvOU9eEkv9hau3mSn0uPsZ83Z5ul3t+C0ZMAhCUYeo+8cOiFcklVvb+qdp5a/9iq+nJVXVxV/1FVPz8s/62q+vDUdmur6gNT78+qqntMHeqQoRfLj6rqz6tqu2G7O1XVx6vqgmHdP1bVLeep672r6rNDXc4dekftOLW+VdVzqurbVXVRVb2pqmpq/W9X1TeGXjdfr6pfHJbvVVX/VFU/HHojT19cj0zy2dbai1trF7bWLmutHZ3kXUleO+w/6an+zKr6XpKPz+29XlV3qKpPDsc+ZajbknpkDed92tAD6LyqesM82/3a8Hn+XFVtV1V/XFX/O7TtB4bAI9V7cb9geL33UM/fGd4fUFUXVndg9VFuL6je4/vc6Rs+VbVTVf1FVX1vqNebq2qXYd2tq48EuHgo71NTn/kfVdU5Q1t8q6oePs/5rJ8abaHyllNr7fOttXcl+c48m+yf5B9ba9e21v43/YbZXZe7HgBsvarqZ6tPh3Rx9SkY5+0IUn3E07nVe/D+nxmb3LqqTh6uiZ+oqv2m9n3jEE9dWlVfrKoHLXCc46rqB9VjuU9W1V2n1r1jiDuOH47zueodnCbr7zrU4cLhev6iYfm8scRcrbUftNbemB43vXbqmj9vjLVAfPPJ4ffF1Xs2z+xwNef8n1E9zpyMLHvaPNv9eVV9uqpuMfy8bfh8zqmqo2qYur2qzqyqew6vnz7ESncZ3j+rqv51eH3k0C7HDsf+WlXda+p4G33+VbVzVb17aPOLq+oLVbXnPOezfvqyBdpzQa21n7TW/qq19ukks2aueFyS17XWrmytnZHkbUlmfZcn2x7XWvtaa+0nSf40yYMn37fW2utaa19qra1rrX0ryb8lecBS6gnA6lLuNS12r2m91to1rbWvJfn1JD9M8oLF2mlYd4N7K1V1UJIXJfn1IY46feFPaumxR1Xdbvg8Xzi8v+9Qp4ur6vQaZhGoPiLuv6f2O6WqPj/1/tNV9cvD6036nsx3/lOf51LuoR1YVWcvVt5iFrmPdP8k57XWjhvuI707/TP+1XnK+t/W2sWTKiW5LskmTXML2wIJQFi6J6f3wr1Dkp9P8owkGYKWtyd5dpLdk7wlyYeqaqckn0jyoOo3h26XZE2GP+Cr6o5Jdk3ylalj/EqSeyX5xfRewZMbB5Xkz9JH1v1skn3Tbx7Ncm2S309y6yT3S/LwJL8zZ5vHJvml9F4yT07y6KFOTxrKPTTJzZM8PskFQ3D44SSnJ9l7KPP3qurRQ3mPTHLcjLp8IMkDquomU8seMpzDo2ds/54kn09vxyOT/OY85zjLG5O8cegBdKfh2NdTPTH32iSPaK19Nb2H0C8PddoryUVJ3jRs/okkB07V+TvD7yR5cJJPtdba8P62SW6R3jbPTPKm2tBT6bVJfjrJPdIDkr2TTKbEfEGSs5PskWTP9AC0VdWdk/xukl8aero9OskZS2iDmeUN5/43VfU3i+z/j0PQ/bGquvsSjjefv0pyaFWtGc7lfklOuRHlAbCKVNWa9LjhY0luk+Tw9GvMDaYPGm7AvDA9lvipJLOeM/O09CTJrZN8Ock/Tq37Qvo1drf0OOK46Rsic5w4HOM2Sb40p5wkeWqSV6SPvFqb5FVDHW+Wfh07KT1eOCDJvw/7LBRLzOefhzrceQkx1nzxzYOH37ccejZ/dqEDVtVNkxyd5OAhtrh/eltOb7NdVf1depz7qNbaJUnemWTdcM6/kORRSSbPuJmOlR6cG8ZKn5gq/vFJ3pfeq/tDSf56csxNPP/D0mOvfdPjxuckuWqhNlikvAw31X5jCWXMp+a8/rkFtpu7bWZtP9w4fVCSr92IegGwdXOvaf444AaGR8j8W/r1ccF2mu/eSmvtpPTR+O8f4qil3P9YNPaoqv3TP5u/bq39RVXtneT4JEelx6ovTPJPVbVHks8mOaB6R+4d0uOAfarqZtU7jd8zyaemit/o78ki95YWvYc210LlVdUDq+rixcqYr+hcPzaaLJsvlkpV/UZVXZrkR+nft7fM2WS57m/BqicBCEt3dGvt+621C9MDlHsMy387yVtaa58beqq8M8nVSe7bWvtOksuGbR+S5KNJzqmqnxnef6q1dt3UMV47jKD7XnoS5alJ0lpb21o7ubV2dWvth0nekA03WK6ntfbF1tp/Dr2Gz0i/CM7d9jWttYuH4/y/qXN5Vnrv5S+0bm1r7cz0AG6P1torhx7Q30nyd0km0xHdOsm5M6pzbvr/M9PD9o9srV3RWpsbKN1+OM7LhmN8Ov0G0VJdkyF4aq1d3lr7zznrfy99qoEDW2trh2XPTvLi1trZrbWr0wPSJw7B1/qAOv0m1uuyoff1Q3L9m1rXJHnl0CPthCSXp9/Uq/Tvx+9PRkamB5lPmdrvdkn2G/adJBWvTbJTkrtU1ZrW2hnDSLqltMGs8tJa+53W2tzgfNrT0kfu7Zf+nfhozdPzbwk+kuSJ6cHwN5O8rbX2hU0sC4DV577pN55eM1zTP55+bXjqjG2fnOQfWmtfba1dkdk3nY5vrX1yuFa/OMn9qmrfJGmtvbu1dsEQ97w+/fo58zklrbW3D7MUTK75d6+qW0xt8s9D7+R16cnBewzLH5vkB62117fWfjyU8blh3UKxxHy+P/zeLYvHWIvFNxvjuiQ/V1W7tNbOHXrRT6xJn4Zyt/Qpk64cerUfnOT3htjt/PSpLid1+0Q2xJgPSr+BOHk/N1b6dGvthOGm3bvSb9TkRpz/Nek3uQ4Y4u8vttYuXUIbzNuerbWfb629ZwllzHJSkj8ebtodkH5j9SbzbHtCkidX1c8PN/helt5ha9b2R6bH0v+wifUCYOvnXtP8ccB8vp8esyzYTtn0eyuzLBZ73CXJqUle3lp767Ds6UlOGGKg61prJyc5LckhrbUfD68fnJ6c/Ur67EkPGOr+7dbaBVPlb/T3ZJHz35QYc97yWmufbq3dcgllzPIfSfaqqqcOHckPS09KzhdLpbX2ntaTlz+d5M1JzptavZz3t2DVkwCEpZt+3seV6Te2kn5BecEw1P7iocfLvuk9qJINvaMnPaFPTQ+S5t4YSZKzpl6fOSmjqm5TVe8bhtlfmuTd6Um3G6iqn64+DeQPhm1fPWPb+c5l3ySzgqH90i/G0+f4ovRRZknvcTNr/vXbpd9sumiec5y2V5ILW2tXLmHbWZ6ZfuH/ZvWpGB47Z/0fJHlTa+3sqWX7pT+HZ3JO30gPaPYcgpjL04OqB6XfuPz+0ONp7md3wXCzcGLSpnukByxfnDrGScPypM9vvjb9WYnfqao/TnoQnp6wPDLJ+cNnv1cWN7O8pWitfaa1dlXrU1f9WZKLh/PeKNWnPTspySuT7Jz+nXp0DdOnArBN2CvJWXNuPJ2Z3rN75rZztptr/frW2uVJLsyGGOkF1aeTumS4zt4iM2Kkqtq+ql5TfarOS7Oh9/P0thsbHyULxBLzbJ9saIcLs3iMtVh8syRDcvXX03urn1t9qtOfmdrkgPQRAa9ofVrKybmtGbaf1O0t6aMXkw2dpW6bZPsk70+f+WH/9M/hy1Plz23bnYck6aae/7vSb3a+r/rUsa+rPvJ0McvSnjM8L73j07fTRyW8N31Whhtorf17kpcn+af07/sZ6Tdxr7d9Vf1u+kiJxwzJZQDGyb2m+eOA+eydHkdNypjZTjfi3sosi8UeT0tyTpIPzjm/J82p2wOz4f7ZxnyGG/09WeT8NzomWub2nC73gvQ49PnpibyD0mffmBlLzdn32+kzJfzN1LJlub8FYyEBCDfeWUle1Vq75dTPTVpr7x3WTy7oDxpeT3pLz7qg7zv1+vbZ0EP8z9J7Bv/80MPl6bnh8PiJv00fdfVTw7YvWmDbWedyp3mWf3fOOd6stXbIsP6UJE+asd+T058NOJ3UazO2S/powd3q+tOF7jvPtjfQWvt2a+2p6TelXpvkg9Wnu5p4VJKXVNWvzTmvg+ec186ttXOG9Z9IH8m247DsE+k3Ym6VOdNmzeNH6TeD7jpV/i1aa7sOdb6stfaC1tod058H8/wa5k8fejM9MD2Ya8M5LdYG85a3CVqW/r2Zdsck17bWjh16Bp6dPuXXIYvsB8B4fD/JvnX959DePv2myFzn5obxz1zr11fVruk9vr9f/Xl/f5Qeb9xq6HV8SWZfv34j/cbCI9KTU/tPilz8dOaNjybrFoolZvmVJOcn+VYWibEWiG/mi6fm1Vr7aGvtkek3nb6Z3sN+4htJfivJibVhqtaz0nuQ33qqbjdvrd11KG9t+g2o5yX5ZOszHfwgyf9NH/E3nQCezyadf+szHbyitXaX9OlMH5seoy3WBovFi5uk9VEVT2ut3XZon+3Sp7Wfb/s3tdZ+qrV2m/RE4A5JvjpZX/1ZmH+c5OFzOq8BsO1wr2mGIb58XDZMj7lgOy1wb2WjYqklxB5Hpt8Dek8Nz0se6vauOXW7aWvtNcP6uQnAhT7D+WzS+W9qTLQp96qWorX2idbaL7XWdkt/HNCds0AsNccOmT9WTzb9/haMggQg3Hh/l+Q5VXWf6m5aVY+p/ryYpF+0H5pkl+EP+E+l92bZPcl/zSnrD6rqVtWntToivSd1ktwsfTTaxdXnEP+DBepzsySXJrl86Nn9/23Eufx9khdW1T2HczmgqvZLv+heWv1hv7sMveh/rqp+adjvFUnuX1Wvqqrdqk9/dHh6MPRHSzlw69M/nJbkyKrasarulx7UrVf9wcfPmLV/VT29qvYYbjZdPCy+dmqTr6W3+5uq6vHDsjcnedVwjqmqParqCVP7fCJ9fvNPDu9PTX+O0adbn8JqsXO6Lv378ZdVdZvhGHvXMJ999Qc1H1BVlf6ZXZvk2qq6c1U9rPrc/j9OTyIuerz5ylvCfrevqgcM7b5zVf1Bek++z8yz/XbVn6+0pr+tnWvDw7//Z1j2G8N2t00fcbDoQ7UBGI3PJbkiyR9Wn8bnwPRr+vtmbPuBJM+oqrsMnYBePmObQ6o/V2TH9GcBfq61dlZ6zLMuyQ+T7FBVL0t/rswsN0tPZl2QPjr/1RtxPh9Jctuq+r3qz1O5WVXdZ1i3WCyxXlXtWX1U18uT/MkQJywYYy0Q3/wwfZaFO06Vv39Vteoj8GYd+/HDjZ2r0+PK68UIw42iFyU5paru1Fo7N/05jq+vqpsP1/U7VdX0dF+TWGlyk+rUOe8Xs0nnX1UPraq7DTfYLk2fxmopMc9i8eJC++5UG54vOYmZalh3p6rafaj/welJ0KPmKWfn4Ryr+hT4b01/Bs9Fw/qnpX8/H9n6VGgAbJvca5oyxJQ/mz7K/rbp05UmC7TTIvdWzkuyf011WKuqI6vq1FknsITY45r0jvE3TfKuodx3J3lcVT16OLedq+rAqtpn2Oc/0hNd907y+danZ98vyX2y4T7UYjbp/DclJlqkPRdUC99HSlX9wvAZ3zzJXyQ5u7X20XnKelZtuMd2lyR/kuH53LWR97dgWyABCDdSa+209Dm3/zp9qsu1GR7GO6z/n/SA6lPD+0uTfCfJZ2Ykkf4tyRfTR5cdn+Rtw/JXpD+s+ZJh+T8vUKUXpvdyvyw9EHj/AtvOPZfjkrwqyXuG/f81yW5DPR+XPh3md9N7Nf19eg/6yZD7B6Y/z+WM9N78v5bk0a21jbnIPi39YdIXpN80eX/6TaoMgcHuSeabl/ygJF+rqsvTH2b8lNbnVJ8+v9PTe2n93XBz5o3pzxn8WFVdNpR9n6ldPpEe5E4Cr0+n3zRcaiCW9ATo2iT/WX2ajFOy4dlEPzW8vzz9AdB/01o7NX1O9dekt/MP0ntkvWgJx5qvvFTVm6vqzfPsd7P03nwXpY/OOCh9NMMFw74PGtp14sHpgd4J6b0Hr0q/QTj5fv9q+sPBL0r/Ln81/XsFwDag9SkkH5/+/LgfpU/Jc2hr7Zsztj0x/Vk0H0+/Xn58RpHvSU+aXZjknunxQtKnYToxvfPJmek3IuabPvzYYZtzknw988cTs87nsiSPTI+FfpA+zeNDh9WLxRJJv6l2RZL/Th8R/6TW2tuHsheMsTJPfNP67AqvSvKZ6tM93Te9d//kHOfaLskL0nv8X5jes/wG03O3/tyYVyb5ePVE4qFJdkxvs4vSp7WanvZ9bqw09/2CNvX802/8fTD9Btw3huO+ewmHnDderKqvDcm3+XwrPebZO/27d1X6Tbqkfy//Oz1+/rMkT2tTz1icU/bO6d/py9NvfH42yUunjnNUesz7haq6fPiZL4YDYKTca1rv14fr9sXpMdcFSe7ZWvv+UPZC7bTQvZXjht8XVNWXhtf7Zv5E0aKxxxAD/+pwnLenx2RPGI75w/Q49Q8y3I9vfYr2LyX5WtswBftnk5zZ+rOXF3Ujzn/Re2gzzFvejPtGc817H2nwh0O5Z6XHmr8yWTGj7Ack+e8hvj5h+Jmc14L3t2BbVK1t9OwxAFtEVb0/yTdbay+vqgcmee4wRQEAAFOq6iVJfthae8tK1wUAYLWpqi+nT78tWQSMhgQgsNUYpnm4ML3n16PSe4Xdr7U2d/oKAAAAAABgHjusdAUAptw2fcqJ3ZOcneT/k/wDAAAAAICNYwQgAAAAAAAAjMh2K10BAAAAAAAAYPlslilAb33rW7f9999/cxQNALDV+OIXv/ij1toey1GW+AkA2BYsV/wkdgIAthWbGj9tlgTg/vvvn9NOO21zFA0AsNWoqjOXqyzxEwCwLViu+EnsBABsKzY1fjIFKAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMiAQgAAAAAAAAjIgEIAAAAAAAAIyIBCAAAAAAAACMyA4rXYFN9axnPSsXX3xxHvKQh+Twww9f6eoAAGz1xE8AABtH/AQArFarNgF47rnn5oorrsjatWtXuioAAKuC+AkAYOOInwCA1coUoAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiEoAAAAAAAAAwIhKAAAAAAAAAMCISgAAAAAAAADAiqzYBePXVV69/fcwxx+SYY45ZwdoAAGz9xE8AABtnOn5KxFAAwOqxw0pXYFNdd91161+vXbt2BWsCALA6iJ8AADbOdPyUiKEAgNVj1Y4ABAAAAAAAAG5IAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAAAAAAAARkQCEAAAAAAAAEZEAhAAAAAAAABGRAIQAP7/9u4+TLKzrBP/9870ZEgILzGJEkKSIQ4irAJKBHZXeZOsScySy9XdRUWIi4qrAiIqSEaSQHDZVZEQfFnIakB8WRUViEkUFoK6ipAooIj6G2GAEFxgIMAASiZ5fn9UVae6prqrejIzXf3053NdfaW7zkvd9Zwzde6cb51TAAAAAAAdEQACAAAAAABARwSAAAAAAAAA0BEBIAAAAAAAAHREAAgAAAAAAAAdEQACAAAAAABAR5bmmamqzk1yRZJtSa5qrb3kiFa1Tu9+97uTJI997GM3thAA1lRVaa1lx44d+amf+qlcddVVqaq86EUvSpL85E/+ZFprec5znpOXv/zleeYzn5mf/dmfTVXlR37kR/Lyl788l1xySZLksssuyyWXXJKTTjppxXPs2bMnz3rWs/LCF74wr371q5fnGT1+xRVX5MQTT8zu3btz4MCB5eW2b9+eF73oRQfNu2vXrhXr37dv36rPPc/01eZd6zUdqrVex0Zazxgt4vp7oX+C5AUveEGuvPLKfOpTn1p1nhNPPHHF9KrKfe5zn+zbty9f/OIXV11uaWnwv1oHDhxYPv6NbN++PaecckpuueWWVFVOP/307N+/P5/85CeTJDt27Mhpp52Wz3/+8/mnf/qnJMkjHvGIvOMd78jS0lIuvPDCvO51r8u2bdty++23r1jvL/7iL+ZDH/pQXvjCF+bMM8/MS1/60lx11VW57rrrcuyxx66o+fjjj8/OnTtXHIe/8IUv5JZbbskxxxyTK6+8MieeeGKe9rSn5dZbb82JJ56Yq666KieddFL27du3fCz97Gc/u1xnkpx88sl53vOel927d+e2225brvFnf/Zn8/CHPzzJ4L16dNy//PLLl9c5euxpT3taLr744nzxi1/MC17wgvze7/3eivf10Xv9M5/5zBX9wU/8xE/kwx/+cK688srlY9++ffvyrGc9KzfffHPOOOOM/NzP/VyS2cfdG2+8MT/+4z+en/7pn15R9+7du5f7l9Gye/bsyfd8z/ckSR71qEflJS+583+ZV1tmlre85S154QtfuPz3aaedlnvd617L65jsI5773OfmIx/5SE499dTs2LFjeVzHx2u9x8bx7TzqlUZjNz72613nav3PodY56nme/vSn52Uve9mKbTbvsofSL02rd/KxPXv25Ad/8AfzxS9+MT/zMz8zd11Hy759+/JjP/Zjef/735+zzjorP/3TP61/mkEPxVb39Kc/Pa961atyxx13pKpyzDHHrOhHTj311Hz0ox89aLlt27bljjvuWNETTVpaWso973nP5Z5o3AknnJB//ud/Xv7/+NE5gsn/r7/99ttzxx13JEke9rCH5V3veleOO+64fOELX0iSg/qyJHnOc56T173uddm7d2/udre75RWveEV+7dd+LW9961tzyimn5OMf//iK+S+55JI85CEPWT4evuQlL8mHP/zh5ff6e93rXst9wTnnnJOLL744yZ3H1f379+fDH/7winU++tGPzgMf+MC86lWvWn7smGOOyStf+co1j0/jx7FRD5gkp59+el72speteE+fdr7kU5/61NTj4I033pgf/dEfzY4dO3LGGWfk6U9/ei655JKZx8vV+qfnPve5ueWWW/Lyl788J554Yi677LJ8y7d8Sy677LIkg770V3/1V1f0Vus9Pu/Zsyc/8AM/sKLfXVpayvbt25d7w/Hj9Kc+9anlY/S0fvNQTb7eJHf53Mxa/dOh9jKjbfUd3/Edee1rX5tLLrkkj3vc4+ZadtSnrmeZaa9ltbEerX/Hjh35+Z//+YU6p5Xc+e8jycL3T7XWm26SVNW2JP+Q5JwkNyd5Z5Jvb6397WrLnH322e3GG288nHUe5PGPf3zuuOOOPPShD11uvgDYPE444YTs378/SXLhhRemtZY3vOENSZKdO3fmgx/8YM4888zs3bt3xWNPfOIT01rLG9/4xjzxiU/Ms5/97BXrveiii7J3796ccMIJ+dznPrc8z+jxnTt35iEPecjyc4278MILD5r36quvXjHPS1/60lWfe57pq8271ms6VGu9jo20njFaxPWPq6qbWmtnH4516Z/g6FtaWlpx0qgHO3fuzM0337z8ui688MK8/vWvX3OZyePw+Lomj5mjY+VLX/rSqcfSkfHj/Phj11xzTZKsWH7aOseXX1payu23377ifX30Xn/mmWeu6A/Ge4nRsW+y1tHrnXWsuOCCC7J///6ZdSd3HnNHbrjhhuXfV1tmlic84QlT98/x8RrvIya3x/hzHeqxca2xGx/79a5ztf7nUOscjf/opO74Npt32UPpl6bVO/nY+L6xnrqOlmnbeLP0T0ejd0pW9k9XXHGF4A8WxLQg73Cta+fOnSuO65OWlpZy/vnnLx8Px+c94YQTcvLJJ0/tC2b1T9PMOj6NH8fGe8Dk4Pf0aedL3v3ud089Do76oPHXtX///pn1zOqfRv3lG9/4xmzbtm3Veg/l+DzZj40brWf8OD167cn0fvNQTb7eJHf53Mxa/dOh9jKT23hpaSlvfvOb51p21KeuZ5lpr2W1sR7vgxftnFZy8Ngtcv80zy1AH5FkT2vt/a21Lyb5zSQXrveJjhQnrwA2p/ED5bXXXpvrrrtu+e+9e/emtbaicRs9dt111+X6669Pay3XX3999u3btzzPnj17lpfZv3//8jw33njj8uN79+7NtddeO7Wm66677qB59+zZszx93759qz73PNNXm/e6667LddddN9dy8xofi8nXsZHWM0aLuP5e6J9goLfwLxm854+/rnlOMk0eh8fXNbn861//+uzZs2fq/OMmw7/RYzfddNPye/XIddddlz179qx4bHz5AwcOrHhfH3+vH+8Pxo/vo2Pfvn37DgpcrrnmmpnH3RtvvHG5hvG6x1/3ddddl3379q045o4873nPS5JVl5nlLW95y6r75/h4TXvtk891qMfGydqTwb4yOfbrXed43eN1jb+m9axzfPxHJ29H22w9y663X5o2rpOPjfeV66nraNm3b99B+861116rf1qD8A8Wx+EK/6ata63wLxn0Jn/wB39w0HmLZPBeP/nYi1/84qnH1XmsdXyaPI5N9g7XXHPN8nv6tPMl11577dTj4HgfNP66ZtWzWv802aON+rDJet/whjcc1FvNe3ye1o+N27t3b2666abl4/T4a08O7jcP1bTXe1fPzazVP910002HtP5p2/jAgQN561vfOnPZ8T513mWmvZbVxnqyD16kc1rJ9LFb5P5pngDwtCTj1yTfPHwMAA6L2267Lbfddtu657399tvzmte8Znna5ZdfftD8t99+ey699NIVj612Qu222247aN7xdb761a9evpXI5HPPM321eW+77bblmmYtN6/JsZg2NhthPWO0iOsH2GzmOTm2nuNwMjimHGp4eskll+TVr371iue77bbbcvnll8+sYfS+Pv5eP76OyZouv/zyqfPefvvtM4+7k/3AqO7x57jtttvymte8Zuox9u1vf3uSrLrMLD/1Uz+16rTReE3rIybnmxyv9RwbJ2sfrXNyO613neN1j/d0469pPetcrccZ3SJrPcuup1+aNq6Tj03uR/PWdbSsto31T9Mt0slHYOON3/Z0lje96U1T33PntdrxadZxa/x4Om3eyWP6aJ5px695nnee/mna84601qb2VvMcn+eZ55JLLlnRh0xzV88jzNrOh3JuZq3+abKvmHf9q23jF7/4xTOXnexT51lmZJ6+dFofvCjntJLpY7fI/dM8AWBNeeyg/4usqu+rqhur6sbJ+yIDwOHSWls+mXngwIG86U1vWp427dNeBw4cmHoVwmrrnpx3fJ1vfvObV3zKafy555m+2rxrvaZDNTkWsz7BeLSsZ4wWcf2Hm/4J2IxGV34div379+fNb37ziuXHryZby+h9ffy9fnwd0+pc7ZZEs4670z71Pq3uN73pTWseY1dbZpa1ThyNxmu8j1htvsnxWs+xcbL28fVO1rqeda7W/4y/pvWsc7Xxn6f/uyv90rRxnXxstSthF8Vq/z4WuX/SOwGb1WrH1Xmsdnya57g1ek+fZ97xKwQPpZ7V+qf1mNZbraf2tezfv39mCHtXzyPMer2Hcm5mrf5prXNYa1ltG88TUk/Os55ge56+dNr6FuWcVrL62C1q/zRPAHhzktPH/r5fklsmZ2qtvbK1dnZr7exTTjnlcNUHACtUVaoGn01ZWlrKOeecszxtdG/1cUtLSznhhBPmXvfkvOPrfMITnpClpaWpzz3P9NXmXes1HarJsZg2NhthPWO0iOs/3PRPwGa0c+fO5ePWep1wwgl5whOesGL5qpprnaP39fH3+vF1TKvzCU94wtR1zTruTvYDq9V9zjnnrHmMXW2ZWSZf32TtO3fuXNFHrDbf5Hit59g4Wfv4eidrXc86V+t/xl/Teta52vjP0//dlX5p2rhOPjathnn70qNhtX8fi9w/bWTvtGvXrqP6fEBfVjuuzmO149M8x63Re/o8847mmXWsmvfYO+qf1mNab7We2tdywgknrNljJXf9PMKs13so52bW6p/WOoe1ltW28azxmTbPPMuMzNOXTlvfopzTSlYfu0Xtn+YJAN+Z5AFVdf+qOjbJk5Ks79tKAWAN27dvz/bt29c977Zt2/KUpzxledru3bsPmn/btm0HXZ6/WnOyffv2g+YdX+dTn/rUHHPMMVOfe57pq827ffv25ZpmLTevybGYNjYbYT1jtIjrB9hs5jnRtJ7jcDI4pqznf/THXXbZZXnqU5+64vm2b9+e3bt3z6xh9L4+/l4/vo7Jmnbv3j113m3bts087k72A6O6x59j+/btecpTnjL1GPuoRz0qSVZdZpbnP//5q04bjde0PmJyvsnxWs+xcbL20Tont9N61zle93hPN/6a1rPO1Xqcyy67bN3Lrqdfmjauk49Nu0XUPHUdLattY/0TwGzbtm2be95zzjln6nvuvFY7Ps06bo0fT6fNO3lMH80z6xagqz3vPP3TtOcdqaqpvdU8x+d55rnssstW9CHT3NXzCLO286Gcm1mrf5rsK+Zd/2rb+OKLL5657GSfOs8yI/P0pdP64EU5p5VMH7tF7p9mBoCttQNJfijJHyZ5X5Lfaq2990gXNq+HPvShG10CAIdg/BMz559/fs4777zlv0dXAYx/wmf02HnnnZdzzz03VZVzzz03J5100vI8u3btWvGJtdE8Z5999vLjO3fuzPnnnz+1pvPOO++gecc/6XvSSSet+tzzTF9t3vPOOy/nnXfeXMvNa3wsJl/HRlrPGC3i+nuhf4KBQz0Js8jGr6JKkic+8Ykzl5k8Do+va3L5Cy+8MLt27Zo6/7jVrnx6+MMfvvxePXLeeedl165dKx4bX35paWnF+/r4e/14fzB+fB8d+0466aRccMEFK+q44IILZh53zz777OUaxusef93nnXdeTjrppBXH3JGXvOQlSbLqMrM8/vGPX3X/HB+vaa998rkO9dg4WXsy2Fcmx3696xyve7yu8de0nnWOj/8o8B5ts/Usu95+adq4Tj423leup66j5aSTTjpo3zn//PP1T2u44YYbNroEYOhQr6abZ12zrjZaWlrKN3/zNx903iIZvNdPPnbxxRdPPa7OY63j0+RxbLJ3uOCCC5bf06edLzn//POnHgfH+6Dx1zWrntX6p8kebdSHTdb7xCc+8aDeat7j87R+bNzOnTvz8Ic/fPk4Pf7ak4P7zUM17fXe1XMza/VPD3/4ww9p/dO28dLSUh73uMfNXHa8T513mWmvZbWxnuyDF+mcVjJ97Ba5f5rnCsC01q5trX1Fa+3LW2vzf6sjAIwZNdU7duzIZZddlgc96EF58IMfvPyJ6Qc/+MF50IMelN27d+erv/qrs3v37uV5Ro+N5h39Pmn37t25+93vnssuu2zFPKPHR1cDPOhBD8oDHvCA5Z9RHZPzTlrrueeZvtq861luXmu9jo10JF7r0Vw/0I/nP//5OfHEE9ecZ3J6VeXUU0/Nscceu+ZyS0tLq96icfv27bnvfe+7PO2MM87Il3zJlyxP37FjR84666zc5z73WX7sEY94xPJ6v/VbvzXJwZ88H10ZNvrU7JlnnpmnPOUpyyebJms+/vjjDzoO3//+98+OHTty3HHHLR8z733vey+Pxei9dfxYOl5nkpx88sm59NJLc7e73W1FjeOfUB4/7o+vc/TYpZdemh07dqSqcvHFFx/0vj56r5/sD77iK75iufbxee93v/slSc4444y5j7uXXnppjjnmmIPqHu9fRsafb3T136xlZpn89PNpp522Yh2TfcSuXbty3HHH5ayzzloxrpPzrsf4dh7fVybHfr3rXK3/OdQ6Rz3Ps5/97IO22bzLHuon8lfbN8f7ytG+vEhX/4089alPzVlnnZUkOeuss/RPwExPf/rTl6/gqaqD+pFTTz116nLbtm2b63bf4z3RuMnbNz772c+eemXZ+JX/D3vYw5Ikxx133PJj02r4kR/5keUQ5W53u1t27969HGpMu93wxRdfvOJ4uGvXrhXv9ePHlPHbAo6Oq6effvpB63z0ox+d7/3e713x2DHHHDPz+DR+HBvvHU4//fSD3tOnnS9Z7Tg4usppx44decADHpBLL710ruPlav3Trl27cvzxxy/3l1/91V+94sqx448//qDear3H5927dx/U7y4tLa3oDceP0+PH6Gn95qGafL2H49zMWv3Toa5/tK2e/OQnJ1nf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\n",
      "text/plain": [
       "<Figure size 1800x1152 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def boxplots_custom(dataset, columns_list, rows, cols, suptitle):\n",
    "    fig, axs = plt.subplots(rows, cols, sharey=True, figsize=(25,16))\n",
    "    fig.suptitle(suptitle,y=1, size=25)\n",
    "    axs = axs.flatten()\n",
    "    for i, data in enumerate(columns_list):\n",
    "        sns.boxplot(data=dataset[data], orient='h', ax=axs[i])\n",
    "        axs[i].set_title(data + ', skewness is: '+str(round(dataset[data].skew(axis = 0, skipna = True),2)))\n",
    "        \n",
    "boxplots_custom(dataset=df, columns_list=numeric_columns, rows=int(numeric_columns.size/3)+1, cols=3, suptitle='Boxplots for each variable')\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e337a1a4",
   "metadata": {},
   "source": [
    "## Feature Engineering (chi2, ANNOVA)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2930c457",
   "metadata": {},
   "source": [
    "### ..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c332c2d4",
   "metadata": {},
   "source": [
    "## Model Oluşturma"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "27c4b245",
   "metadata": {},
   "outputs": [],
   "source": [
    "#df.drop(columns=['type','nameOrig','nameDest'], inplace=True)\n",
    "df.drop(columns=['nameOrig','nameDest'], inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "fbfdd9af",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df.drop('isFraud', axis=1)\n",
    "y = df['isFraud']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c8b3196b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#scaler = StandardScaler()\n",
    "#X_scaled = scaler.fit_transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "26d9e3d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "#X_train, X_test, y_train, y_test = train_test_split(X_chi2, y, test_size = 0.30, random_state=42)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state=42, stratify=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "4ee6f83f",
   "metadata": {},
   "outputs": [],
   "source": [
    "sc = StandardScaler()\n",
    "X_train = sc.fit_transform(X_train)\n",
    "X_test = sc.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "4d440bbf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Non-Frauds: 4448085 / 50.0 % of the dataset\n",
      "Frauds: 4448085 / 50.0 % of the dataset\n"
     ]
    }
   ],
   "source": [
    "X_train_ros, y_train_ros = balance.balancedWithRandomOverSampler(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "542b1cfa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Non-Frauds: 5749 / 50.0 % of the dataset\n",
      "Frauds: 5749 / 50.0 % of the dataset\n"
     ]
    }
   ],
   "source": [
    "X_train_rus, y_train_rus = balance.balancedWithRandomUnderSampler(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "8515b603",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Non-Frauds: 4448085 / 50.0 % of the dataset\n",
      "Frauds: 4448085 / 50.0 % of the dataset\n"
     ]
    }
   ],
   "source": [
    "X_train_smote, y_train_smote = balance.balanceWithSMOTE(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "11c9d720",
   "metadata": {},
   "outputs": [],
   "source": [
    "params = {\n",
    "    'n_estimators': 100,\n",
    "    'n_jobs': -1\n",
    "}\n",
    "\n",
    "ml_models = [ lgb.LGBMClassifier(**params)\n",
    "             , XGBClassifier(**params)] \n",
    "             #, AdaBoostClassifier()\n",
    "             #,GradientBoostingClassifier(),CatBoostClassifier()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "f9238ef8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "***** LGBMClassifier_baseline DONE *****\n",
      "***** LGBMClassifier_RandomOverSampler DONE *****\n",
      "***** LGBMClassifier_RandomUnderSampler DONE *****\n",
      "***** LGBMClassifier_SMOTE DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[11:55:23] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_baseline DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[11:58:41] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_RandomOverSampler DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:06:00] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_RandomUnderSampler DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:06:09] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_SMOTE DONE *****\n"
     ]
    }
   ],
   "source": [
    "for i in ml_models:\n",
    "    mtap.model_performance(i, X_train, X_test, y_train, y_test, \"baseline\")\n",
    "    mtap.model_performance(i, X_train_ros, X_test, y_train_ros, y_test, \"RandomOverSampler\")\n",
    "    mtap.model_performance(i, X_train_rus, X_test, y_train_rus, y_test, \"RandomUnderSampler\")\n",
    "    mtap.model_performance(i, X_train_smote, X_test, y_train_smote, y_test, \"SMOTE\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "1609a056",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>model_name</th>\n",
       "      <th>precision</th>\n",
       "      <th>recall</th>\n",
       "      <th>f1_score</th>\n",
       "      <th>AUC</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>XGBClassifier_baseline</td>\n",
       "      <td>0.966884</td>\n",
       "      <td>0.841315</td>\n",
       "      <td>0.899740</td>\n",
       "      <td>0.920639</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>XGBClassifier_RandomOverSampler</td>\n",
       "      <td>0.463051</td>\n",
       "      <td>0.984172</td>\n",
       "      <td>0.629788</td>\n",
       "      <td>0.991348</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>XGBClassifier_SMOTE</td>\n",
       "      <td>0.333516</td>\n",
       "      <td>0.989448</td>\n",
       "      <td>0.498875</td>\n",
       "      <td>0.993446</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>LGBMClassifier_baseline</td>\n",
       "      <td>0.544065</td>\n",
       "      <td>0.433442</td>\n",
       "      <td>0.482494</td>\n",
       "      <td>0.716486</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>LGBMClassifier_RandomOverSampler</td>\n",
       "      <td>0.254527</td>\n",
       "      <td>0.992695</td>\n",
       "      <td>0.405168</td>\n",
       "      <td>0.994468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>LGBMClassifier_SMOTE</td>\n",
       "      <td>0.203891</td>\n",
       "      <td>0.991071</td>\n",
       "      <td>0.338204</td>\n",
       "      <td>0.993035</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>LGBMClassifier_RandomUnderSampler</td>\n",
       "      <td>0.137572</td>\n",
       "      <td>0.997565</td>\n",
       "      <td>0.241798</td>\n",
       "      <td>0.994741</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>XGBClassifier_RandomUnderSampler</td>\n",
       "      <td>0.120459</td>\n",
       "      <td>0.997159</td>\n",
       "      <td>0.214951</td>\n",
       "      <td>0.993874</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                          model_name  precision    recall  f1_score       AUC\n",
       "4             XGBClassifier_baseline   0.966884  0.841315  0.899740  0.920639\n",
       "5    XGBClassifier_RandomOverSampler   0.463051  0.984172  0.629788  0.991348\n",
       "7                XGBClassifier_SMOTE   0.333516  0.989448  0.498875  0.993446\n",
       "0            LGBMClassifier_baseline   0.544065  0.433442  0.482494  0.716486\n",
       "1   LGBMClassifier_RandomOverSampler   0.254527  0.992695  0.405168  0.994468\n",
       "3               LGBMClassifier_SMOTE   0.203891  0.991071  0.338204  0.993035\n",
       "2  LGBMClassifier_RandomUnderSampler   0.137572  0.997565  0.241798  0.994741\n",
       "6   XGBClassifier_RandomUnderSampler   0.120459  0.997159  0.214951  0.993874"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mtap.all_performances.sort_values(by=['f1_score'], ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "6cec02a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import StratifiedKFold\n",
    "\n",
    "kf = StratifiedKFold(n_splits=5, shuffle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "044255d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "params = {\n",
    "    'n_estimators': [50, 100, 200],\n",
    "    'max_depth': [4, 6, 10, 12],\n",
    "    'random_state': [13]\n",
    "}\n",
    "\n",
    "grid_rf = GridSearchCV(lgb.LGBMClassifier(**params), param_grid=params,\n",
    "                       cv=kf, scoring='recall').fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "c8eaa053",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best parameters: {'max_depth': 12, 'n_estimators': 50, 'random_state': 13}\n",
      "Best score: 0.5141818594619139\n"
     ]
    }
   ],
   "source": [
    "print('Best parameters:', grid_rf.best_params_)\n",
    "print('Best score:', grid_rf.best_score_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ef6c9573",
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = grid_rf.predict(X_test)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23161f55",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "863c3078",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6daf3136",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "65e85ec1",
   "metadata": {},
   "outputs": [],
   "source": [
    "params = {\n",
    "    'n_estimators': 100,\n",
    "    'n_jobs': 3\n",
    "}\n",
    "\n",
    "ml_models = [ lgb.LGBMClassifier(**params)\n",
    "             , XGBClassifier(**params)] \n",
    "             #, AdaBoostClassifier()\n",
    "             #,GradientBoostingClassifier(),CatBoostClassifier()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "eda34c5c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "***** LGBMClassifier_baseline DONE *****\n",
      "***** LGBMClassifier_RandomOverSampler DONE *****\n",
      "***** LGBMClassifier_RandomUnderSampler DONE *****\n",
      "***** LGBMClassifier_SMOTE DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:19:04] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_baseline DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:23:56] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_RandomOverSampler DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:34:22] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_RandomUnderSampler DONE *****\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12:34:34] WARNING: C:/Users/Administrator/workspace/xgboost-win64_release_1.5.1/src/learner.cc:1115: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'binary:logistic' was changed from 'error' to 'logloss'. Explicitly set eval_metric if you'd like to restore the old behavior.\n",
      "***** XGBClassifier_SMOTE DONE *****\n"
     ]
    }
   ],
   "source": [
    "for i in ml_models:\n",
    "    mtap.model_performance(i, X_train, X_test, y_train, y_test, \"baseline\")\n",
    "    mtap.model_performance(i, X_train_ros, X_test, y_train_ros, y_test, \"RandomOverSampler\")\n",
    "    mtap.model_performance(i, X_train_rus, X_test, y_train_rus, y_test, \"RandomUnderSampler\")\n",
    "    mtap.model_performance(i, X_train_smote, X_test, y_train_smote, y_test, \"SMOTE\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "e37bb16f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>model_name</th>\n",
       "      <th>precision</th>\n",
       "      <th>recall</th>\n",
       "      <th>f1_score</th>\n",
       "      <th>AUC</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>XGBClassifier_baseline</td>\n",
       "      <td>0.966884</td>\n",
       "      <td>0.841315</td>\n",
       "      <td>0.899740</td>\n",
       "      <td>0.920639</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>XGBClassifier_RandomOverSampler</td>\n",
       "      <td>0.463051</td>\n",
       "      <td>0.984172</td>\n",
       "      <td>0.629788</td>\n",
       "      <td>0.991348</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>LGBMClassifier_baseline</td>\n",
       "      <td>0.585628</td>\n",
       "      <td>0.552354</td>\n",
       "      <td>0.568505</td>\n",
       "      <td>0.775924</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>XGBClassifier_SMOTE</td>\n",
       "      <td>0.333516</td>\n",
       "      <td>0.989448</td>\n",
       "      <td>0.498875</td>\n",
       "      <td>0.993446</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>LGBMClassifier_baseline</td>\n",
       "      <td>0.544065</td>\n",
       "      <td>0.433442</td>\n",
       "      <td>0.482494</td>\n",
       "      <td>0.716486</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>LGBMClassifier_RandomOverSampler</td>\n",
       "      <td>0.254527</td>\n",
       "      <td>0.992695</td>\n",
       "      <td>0.405168</td>\n",
       "      <td>0.994468</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>LGBMClassifier_SMOTE</td>\n",
       "      <td>0.203891</td>\n",
       "      <td>0.991071</td>\n",
       "      <td>0.338204</td>\n",
       "      <td>0.993035</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>LGBMClassifier_RandomUnderSampler</td>\n",
       "      <td>0.137572</td>\n",
       "      <td>0.997565</td>\n",
       "      <td>0.241798</td>\n",
       "      <td>0.994741</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>XGBClassifier_RandomUnderSampler</td>\n",
       "      <td>0.120459</td>\n",
       "      <td>0.997159</td>\n",
       "      <td>0.214951</td>\n",
       "      <td>0.993874</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                          model_name  precision    recall  f1_score       AUC\n",
       "4             XGBClassifier_baseline   0.966884  0.841315  0.899740  0.920639\n",
       "5    XGBClassifier_RandomOverSampler   0.463051  0.984172  0.629788  0.991348\n",
       "8            LGBMClassifier_baseline   0.585628  0.552354  0.568505  0.775924\n",
       "7                XGBClassifier_SMOTE   0.333516  0.989448  0.498875  0.993446\n",
       "0            LGBMClassifier_baseline   0.544065  0.433442  0.482494  0.716486\n",
       "1   LGBMClassifier_RandomOverSampler   0.254527  0.992695  0.405168  0.994468\n",
       "3               LGBMClassifier_SMOTE   0.203891  0.991071  0.338204  0.993035\n",
       "2  LGBMClassifier_RandomUnderSampler   0.137572  0.997565  0.241798  0.994741\n",
       "6   XGBClassifier_RandomUnderSampler   0.120459  0.997159  0.214951  0.993874"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mtap.all_performances.sort_values(by=['f1_score'], ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb4b52c5",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc94dd64",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df2688cd",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b77908de",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "e5b231a2",
   "metadata": {},
   "source": [
    "### Feature selection with correlation-matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0763dede",
   "metadata": {},
   "source": [
    "corr_matrix = df.corr()\n",
    "corr_matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a3b70f1",
   "metadata": {},
   "source": [
    "corr_threshold = 0.2 or -0.2\n",
    "\n",
    "# Select highly correlated features\n",
    "#high_corr_features = corr_matrix[abs(corr_matrix['isFraud']) > corr_threshold]['isFraud'].index.tolist()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fef640f3",
   "metadata": {},
   "source": [
    "for i in df.columns:\n",
    "    high_corr_features = corr_matrix[abs(corr_matrix[i]) > corr_threshold].index.tolist()\n",
    "    print(high_corr_features)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e433ea9",
   "metadata": {},
   "source": [
    "df_selected = df[high_corr_features + ['isFraud']]\n",
    "df_selected"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94131c79",
   "metadata": {},
   "source": [
    "plt.figure(figsize=(10,5)) \n",
    "sns.heatmap(df.corr(),annot=True);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "922f87db",
   "metadata": {},
   "source": [
    "X = df_selected.drop('isFraud', axis=1)\n",
    "y = df_selected['isFraud']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a48a5f8",
   "metadata": {},
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14c17f41",
   "metadata": {},
   "source": [
    "for i in ml_models:\n",
    "    function.model_performance(i, X_train, X_test, y_train, y_test, \"baseline_corr\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28c27e55",
   "metadata": {},
   "source": [
    "function.all_performances.sort_values(by=['f1_score'], ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b4e015f3",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e11d5d3",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d5f0ed36",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36376b9b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eca5fa98",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16cf0097",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52f9c086",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b066e5e2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc66e97a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1504774a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
